#pragma once

class InstanceService
{
public:
	InstanceService();
	~InstanceService();

public:
	struct Packet {
		enum Type {
			Instance,
			Player,
		};
		Type type;
		union {
			size_t gsIdx;
			ObjGUID guid;
		};
		INetPacket* pck = NULL;
	};
	static Packet NewInstancePacket(size_t gsIdx, INetPacket* pck);
	static Packet NewPlayerPacket(ObjGUID guid, INetPacket* pck);
protected:
	void PushRecvPacket(const Packet& packet);
	void UpdateAllPackets();
	virtual int HandleInstancePacket(const Packet& packet) = 0;
	virtual int HandlePlayerPacket(const Packet& packet) = 0;
private:
	int HandleOneRecvPacket(const Packet& packet);
	int HandleOneRecvInstancePacket(const Packet& packet);
	int HandleOneRecvPlayerPacket(const Packet& packet);
	MultiBufferQueue<Packet, 1024> m_PacketStorage;

public:
	void AddEventSafe(std::function<void()>&& e);
	void AddEvent(std::function<void()>&& e);
	void AddEvent(LuaRef&& e);
protected:
	void UpdateAllSafeEvents();
	void UpdateAllFrameEvents();
private:
	MultiBufferQueue<std::function<void()>> m_SafeEventStorage;
	std::queue<std::function<void()>> m_NativeEventStorage;
	std::queue<LuaRef> m_ScriptEventStorage;
};
